<?php

namespace App\Command;

use App\Base\ViewsInList;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;

class LazyMoCreateCommand extends Command
{

    protected static $defaultName = 'lazy:mo:create';
    private $updateAll = 1;//覆盖更新

    /**@var $serializer Serializer */
    private $serializer;//覆盖更新
    private $systemTable = [];
    private $readyTable = [];
    private $io;

    public function __construct(SerializerInterface $serializer)
    {
        $this->serializer = $serializer;
        parent::__construct();
    }

    protected function configure()
    {
        $this
            ->setDescription('生成数据库CURD')
            ->addArgument('en', InputArgument::OPTIONAL, 'Entity Name')
            ->addOption('option1', null, InputOption::VALUE_NONE, 'Option description');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {

//        $this->serializer = $this->getContainer()->get('serializer');

        $io = new SymfonyStyle($input, $output);
        $this->io = $io;
        $entity = $input->getArgument('en');

        if ($entity) {
            $io->note(sprintf('You passed an argument: %s', $entity));
        }
        $count = 0;
        if ($entity == "all") {
            $root = str_replace("src/Command", "", __DIR__);//E:\www\symfony4\src\Command
            $dirEntity = $root . "src/Entity";
            is_dir($dirEntity) OR mkdir($dirEntity, 0777, true);
            //查找Entity
            $entityList = scandir($dirEntity);
            foreach ($entityList as $item) {
                $array = mb_split("\.", $item);
                if ($array[count($array) - 1] != "php") {
                    continue;
                }
                $itemName = $array[0];
                if (in_array($itemName, $this->systemTable)) {
                    //系统表永远不能覆盖
                    continue;
                }
                if (in_array($itemName, $this->readyTable) && $this->updateAll == 0) {
                    //已完成的表如果开启覆盖可以覆盖
                    continue;
                }
                $this->createEntityData($itemName);
                print_r($itemName . "已处理\n");
                $count++;
            }
        } else {
            $this->createEntityData($entity);
            $count++;
        }

        $io->success("处理了：$count 项");
        return 200;
    }


    public function createEntityData($itemName)
    {
        if (!$itemName) {
            return;
        }
        if (strpos($itemName, "/") > 0) {
            $arr = explode("/", $itemName);
            $dir = $arr[0] . DIRECTORY_SEPARATOR;
            $itemName = $arr[1];
            $nameSpace = "\\{$arr[0]}";
        } else {
            $dir = "";
            $nameSpace = "";
        }
        if (strpos($itemName, "\\") > 0) {
            $arr = explode("\\", $itemName);
            $dir = $arr[0] . DIRECTORY_SEPARATOR;
            $itemName = $arr[1];
            $nameSpace = "\\{$arr[0]}";
        } else {
            $dir = "";
            $nameSpace = "";
        }

        $sp = DIRECTORY_SEPARATOR;
        $targetBundle = "App";
//        $dirTemplate = str_replace("src{$sp}Command","LazyAdminSrc{$sp}",__DIR__);//E:\www\symfony4\src\Command
//        $LazyAdminSrcDir = $dirTemplate;//E:\www\symfony4\LazyAdminSrc\
//        $LazyAdminSrcDir = "..{$sp}src{$sp}";
        $LazyAdminSrcDir = ".{$sp}src{$sp}";
//        dd(scandir($LazyAdminSrcDir));
        $dirControllerAdminApi = $LazyAdminSrcDir . "Controller{$sp}AdminApi{$sp}{$dir}";
        is_dir($dirControllerAdminApi) OR mkdir($dirControllerAdminApi, 0777, true);
        $dirControllerApi = $LazyAdminSrcDir . "Controller{$sp}Api{$sp}{$dir}";
        is_dir($dirControllerApi) OR mkdir($dirControllerApi, 0777, true);
//        $dirTemplate =  str_replace("LazyAdminSrc{$sp}","",$LazyAdminSrcDir)."Template";is_dir($dirTemplate) OR mkdir($dirTemplate, 0777, true);
        $dirTemplate = ".{$sp}Template";

        $entityName = "App{$sp}Entity{$sp}{$dir}" . $itemName;
        $entity = new $entityName();

        $keys = $this->toArray($entity);
        //2.创建Controller
        //检查文件是否存在
        //AdminApiController
        if (!file_exists($dirControllerAdminApi . $sp ."". $itemName . "AdminApiController.php") || $this->updateAll) {
            $cTpl = file_get_contents($dirTemplate . "{$sp}SAMPLEAdminApiController.php");
            $cTpl = str_replace("__TARGET_BUNDLE__", $targetBundle, $cTpl);
            $cTpl = str_replace("__TARGET_ENTITY_ROOT_NAME__", lcfirst($itemName), $cTpl);
            $cTpl = str_replace("__TARGET_ENTITY__", $itemName, $cTpl);
            $cTpl = str_replace("__NAME_SPACE__", $nameSpace, $cTpl);
            file_put_contents($dirControllerAdminApi . $sp ."". $itemName . "AdminApiController.php", $cTpl);

        } else {
            $this->io->error("{$itemName}AdminApiController 已经存在");
            die(200) ;
        }
        //ApiController
        if (!file_exists($dirControllerApi . "{$sp}" . $itemName . "ApiController.php") || $this->updateAll) {
            $cTpl = file_get_contents($dirTemplate . "{$sp}SAMPLEApiController.php");
            $cTpl = str_replace("__TARGET_BUNDLE__", $targetBundle, $cTpl);
            $cTpl = str_replace("__TARGET_ENTITY_ROOT_NAME__", lcfirst($itemName), $cTpl);
            $cTpl = str_replace("__TARGET_ENTITY__", $itemName, $cTpl);
            $cTpl = str_replace("__NAME_SPACE__", $nameSpace, $cTpl);
            file_put_contents($dirControllerApi . "{$sp}" . $itemName . "ApiController.php", $cTpl);
        } else {
            $this->io->success("{$itemName}ApiController 已经存在");
            die(200) ;
        }
    }

    /**
     * @param $entity
     * @return array
     */
    private function toArray(&$entity)
    {
        if (!$entity) return [];
        $methods = (get_class_methods(get_class($entity)));
        $arrData = array();
        foreach ($methods as $method) {
            if ($method == "__construct") {
                continue;
            }
            if (substr($method, 0, 3) !== "set") {
                continue;
            }

            $attr = lcfirst(substr($method, 3));
            $arrData[$attr] = "";
        }
        $entity = $arrData;
        return $arrData;
    }
}
